<template>
  <div id="app">
    <div>
      <input type="text" placeholder="姓名" />
    </div>
    <div>
      <input type="text" placeholder="身份证" />
    </div>
    <div>
      <input type="text" placeholder="手机号" />
    </div>
    <div>
      {{ message }}
    </div>
    <div>
      <input type="text" placeholder="姓名" />
    </div>
    <div>
      <input type="text" placeholder="身份证" />
    </div>
    <div>
      <input type="text" placeholder="手机号" />
    </div>
    <div>
      {{ message }}
    </div>
    <div>
      <input type="text" placeholder="姓名" />
    </div>
    <div>
      <input type="text" placeholder="身份证" />
    </div>
    <div>
      <input type="text" placeholder="手机号" />
    </div>
    <div @click="startReplay(1)" class="button">
      点击查看回放 数据来自localStorage
    </div>
    <div @click="startReplay(2)" class="button">
      点击查看回放 数据来自node mongo
    </div>
    <div @click="save" class="button">点击保存录屏记录</div>
    <div class="rrweb">
      <h2>录屏回访区域</h2>
    </div>

    <div class="hello-world">
      <img alt="Vue logo" src="./assets/logo.png" />
      <HelloWorld msg="Welcome to Your Vue.js App" />
    </div>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
import * as rrweb from "rrweb";
import RrwebPlayer from "rrweb-player";
import * as api from "./api";
// import {LZString} from "./utils/lzString"

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return {
      events: [],
      message: "hello world! ",
      saveEvents: [],
      stopRecord: null,
      rrwebId: 0,
      setRrwebId: false,
      ws: null,
      ws_timer: null,
      reRonnect: 0, // websocket失败重新链接次数
    };
  },
  mounted() {
    this.initRrweb();
    this.initWebsocket();
  },
  methods: {
    initRrweb() {
      this.rrwebId =
        window.localStorage.getItem("rrwebId") || this.getTime() + "000";
      if (!this.setRrwebId) {
        // 确保只保存一次 用来模拟录屏数据ID
        this.rrwebId++;
        window.localStorage.setItem("rrwebId", this.rrwebId);
        this.setRrwebId = true;
      }
      this.$nextTick(() => {
        this.startRrweb();
      });
    },
    startRrweb() {
      // 开始录屏
      const _this = this;
      this.stopRecord = rrweb.record({
        emit(event) {
          console.log(event);
          // console.log(_this);
          _this.events.push(event);
          // console.log(_this.events);
        },
        inlineStylesheet: false,
        // packFn: pack,
        sampling: {
          // 不录制鼠标移动事件
          mousemove: false,
          // // 不录制鼠标交互事件
          // mouseInteraction: false,
          // // 设置滚动事件的触发频率
          scroll: 150, // 每 150ms 最多触发一次
          // 设置输入事件的录制时机
          // input: "last", // 连续输入时，只录制最终值
        },
        blockClass: new RegExp(
          [
            "timer0",
            "seconds",
            "milliseconds",
            "timer0-area",
            "swiper-item",
          ].join("|"),
          "gi"
        ),
        // ignoreClass: new RegExp([ "timer0", "seconds", "milliseconds", "timer0-area" ].join('|'), 'gi')
      });
    },
    async startReplay(type) {
      // 点击查看回放
      // 查询录屏数据
      // type 1: localstorage    2: 走接口
      const rrwebDom = document.querySelector(".rrweb");
      const rrplayerDom = document.querySelector(".rr-player");
      if (rrplayerDom) {
        // 手动删除 这样不会点多次次查看回放 就有多少个回放的内容
        rrwebDom.removeChild(rrplayerDom);
      }
      let events;
      const params = {
        id: window.localStorage.getItem("rrwebId"),
      };
      if (+type === 1) {
        events = JSON.parse(window.localStorage.getItem("events")).events;
      } else if (+type === 2) {
        await api.rrweb.list(params).then((res) => {
          res = res.data;
          if (res.success) {
            events = JSON.parse(res.bean.events).events;
            console.log("events:");
            console.log(events);
          } else {
            events = JSON.parse(window.localStorage.getItem("events")).events;
          }
          console.log(res);
        });
      }

      // 停止录制
      // console.log(unpack)
      this.stopRecord();
      if (events && events.length > 0) {
        console.log(`events.length: ${events.length}`);
        new RrwebPlayer({
          target: document.querySelector(".rrweb"),
          data: {
            events: events,
            autoPlay: true,
          },
        });
      }
    },
    save() {
      let events =
        (window.localStorage.getItem("events") &&
          JSON.parse(window.localStorage.getItem("events")).events) ||
        [];
      if (!(events instanceof Array)) {
        console.log(events);
        console.log("events 不是数组");
        events = [];
      }
      events = events.concat(this.events);
      events = JSON.stringify({ events });
      window.localStorage.setItem("events", events);
      // this.rrwebId 用来区分哪一份录屏数据

      const params = {
        events,
        id: +this.rrwebId,
      };
      api.rrweb.save(params).then((res) => {
        console.log(res);
        if (res.success) {
          this.events = [];
        }
      });
      console.log("保存数据");
    },
    async initWebsocket() {
      await api.rrweb.ws();
      // websocket请求地址 参数通过url提交
      const ws = new WebSocket(`ws://192.168.1.166:3036/rrweb`);
      this.ws = ws;
      ws.onopen = () => {
        if (this.ws_timer) {
          clearInterval(this.ws_timer);
        }
        this.ws_timer = setInterval(() => {
          let params = {
            events: this.events,
            id: +this.rrwebId,
          };
          params = JSON.stringify(params);
          // 通过LZString压缩
          // console.log(`压缩前长度: ${params.length}`)
          // params = LZString.compressToBase64(params)
          // console.log(`压缩后长度:${params.length}`)
          this.ws.send(params);
        }, 3000);
      };
      (ws.onmessage = (e) => {
        const res = JSON.parse(e.data);
        // const _toString = Object.prototype.toString
        // console.log(_toString.call(e.data))
        if (res.success) {
          // 清空当前this.events
          this.throttle(() => {
            // 节流实现5s打印一次
            console.log(`ws.onmessage = e =>   e.data:`);
            console.log(e.data);
            console.log(`重置this.events数组`);
          }, 5000)();
          this.events = [];
        }
      }),
        (ws.onclose = function(evt) {
          console.log("Connection closed.");
          console.log(evt);
          if (this.ws_timer) {
            clearInterval(this.ws_timer);
          }
          if (+this.reRonnect < 3) {
            console.log(
              "重新连接websocket 防止上一次链接时 node的websocket还没启动好"
            );
            setTimeout(() => {
              this.initWebsocket();
              this.reRonnect++;
            }, 2000);
          }
        });
    },
    getTime() {
      let date = new Date();
      let year = date.getFullYear();
      let month = date.getMonth() + 1;
      let strDate = date.getDate();
      if (month >= 1 && month <= 9) {
        month = "0" + month;
      }
      if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
      }
      let currentdate = `${year}${month}${strDate}`;
      return currentdate;
    },
    throttle(fn, wait = 50) {
      // 节流函数
      // 上一次执行的时间
      let lastTime = 0;
      return function(...args) {
        // 当前时间 单位毫秒
        let now = +new Date();
        // 将当前时间和上一次执行时间对比
        // 如果大于设置的await就执行函数
        if (now - lastTime > wait) {
          fn.apply(this, args);
          lastTime = now;
        }
      };
    },
  },
};
</script>

<!-- <style lang="scoped">
@import url("../node_modules/rrweb-player/dist/style.css");
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;

  .button {
    border: 1px solid #999;
    text-align: center;
    margin: 20px auto;
    width: 20%;
    padding: 10px;

    &:hover {
      background: orange;
    }
  }
  > div {
    margin: 20px auto;
  }
  .rrweb {
    margin: 50px auto 30px;
    position: relative;
    max-width: 1024px;

    &:after {
      clear: both;
      content: "";
      display: table;
    }
  }
}
</style> -->
